import type { KnowledgeDetail } from '@/types/knowledge';

/**
 * JVM知识点数据
 */
export const jvmKnowledge : KnowledgeDetail[] = [
	{
		id: 26,
		title: 'JVM内存模型',
		description: '理解堆、栈、方法区等内存区域，掌握Java程序运行原理，是性能优化的基础。',
		icon: '🧠',
		categoryId: 'jvm',
		categoryName: 'Java内存模型与JVM',
		categoryIcon: '💻',
		difficulty: '高级',
		color: 'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)',
		headerBg: 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)',
		tagBg: 'linear-gradient(135deg, #34495e 0%, #2c3e50 100%)',
		tagColor: '#ffffff',
		difficultyBg: 'linear-gradient(135deg, #c0392b 0%, #8e44ad 100%)',
		keyPoints: [
			{
				point: '程序计数器（Program Counter）：记录当前线程执行的字节码行号，线程私有，唯一不会OOM的区域。',
				code: `// 程序计数器示例说明
public class PCDemo {
    public static void main(String[] args) {
        int i = 0;          // PC: 指向 iconst_0
        i = i + 1;          // PC: 指向 iadd
        System.out.println(i);  // PC: 指向 invokevirtual
    }
}

// 字节码（使用 javap -c PCDemo 查看）
// 0: iconst_0        // PC = 0
// 1: istore_1        // PC = 1
// 2: iload_1         // PC = 2
// 3: iconst_1        // PC = 3
// 4: iadd            // PC = 4
// 5: istore_1        // PC = 5
// 6: getstatic      // PC = 6
// 9: iload_1         // PC = 9
// 10: invokevirtual  // PC = 10

// 多线程时，每个线程都有自己的PC
public class MultiThreadPC {
    public static void main(String[] args) {
        new Thread(() -> method("线程1")).start();
        new Thread(() -> method("线程2")).start();
        // 两个线程各自维护独立的PC，互不干扰
    }
    
    static void method(String name) {
        System.out.println(name + " 执行中");
    }
}`
			},
			{
				point: '虚拟机栈（VM Stack）：线程私有，存储局部变量、操作数栈、动态链接、方法出口等信息。',
				code: `// 虚拟机栈示例
public class StackDemo {
    public static void main(String[] args) {
        int result = calculate(5, 3);  // main方法的栈帧
        System.out.println(result);
    }
    
    public static int calculate(int a, int b) {  // calculate方法的栈帧
        int sum = add(a, b);  // add方法的栈帧入栈
        return sum;  // add方法栈帧出栈
    }
    
    public static int add(int x, int y) {
        int result = x + y;  // 局部变量存储在栈帧的局部变量表中
        return result;
    }
}

// 栈帧结构示意：
// ┌─────────────────┐
// │  方法出口信息    │
// ├─────────────────┤
// │  动态链接        │
// ├─────────────────┤
// │  操作数栈        │
// ├─────────────────┤
// │  局部变量表      │
// │  - 参数          │
// │  - 局部变量      │
// └─────────────────┘

// StackOverflowError 示例
public class StackOverflow {
    private static int count = 0;
    
    public static void recursion() {
        count++;
        recursion();  // 无限递归，最终栈溢出
    }
    
    public static void main(String[] args) {
        try {
            recursion();
        } catch (StackOverflowError e) {
            System.out.println("递归深度: " + count);
            // 输出: 递归深度: 约10000-20000（取决于-Xss设置）
        }
    }
}`
			},
			{
				point: '堆内存（Heap）：所有线程共享，存储对象实例和数组，是GC的主要区域，分为新生代和老年代。',
				code: `// 堆内存示例
public class HeapDemo {
    // 实例变量存储在堆中
    private String name;
    private int age;
    
    public HeapDemo(String name, int age) {
        this.name = name;  // 对象存储在堆中
        this.age = age;
    }
    
    public static void main(String[] args) {
        // 对象在堆中分配
        HeapDemo obj1 = new HeapDemo("张三", 25);  // 堆中
        HeapDemo obj2 = new HeapDemo("李四", 30);  // 堆中
        
        // 数组也在堆中
        int[] array = new int[1000];  // 堆中
        
        // 引用在栈中，对象在堆中
        // Stack: obj1 -> Heap: HeapDemo@123
        // Stack: obj2 -> Heap: HeapDemo@456
    }
}

// 堆内存结构（JDK 8+）
// ┌──────────────────────┐
// │   新生代 (Young Gen)  │
// │  ┌────────────────┐  │
// │  │ Eden区 (8)     │  │
// │  ├────────────────┤  │
// │  │ Survivor0 (1)  │  │
// │  ├────────────────┤  │
// │  │ Survivor1 (1)  │  │
// │  └────────────────┘  │
// ├──────────────────────┤
// │   老年代 (Old Gen)    │
// │                      │
// └──────────────────────┘

// OutOfMemoryError: Java heap space
public class HeapOOM {
    public static void main(String[] args) {
        // VM参数：-Xms20m -Xmx20m
        List<byte[]> list = new ArrayList<>();
        while (true) {
            list.add(new byte[1024 * 1024]);  // 每次1MB
            // 最终抛出 OutOfMemoryError
        }
    }
}`
			},
			{
				point: '方法区（Method Area）/元空间（Metaspace）：存储类信息、常量、静态变量、JIT编译后的代码，JDK8后改为元空间。',
				code: `// 方法区示例
public class MethodAreaDemo {
    // 静态变量 - 存储在方法区/元空间
    private static int staticVar = 100;
    private static final String CONSTANT = "常量";
    
    // 实例变量 - 存储在堆中
    private int instanceVar = 200;
    
    public static void main(String[] args) {
        // 类信息存储在方法区
        Class<MethodAreaDemo> clazz = MethodAreaDemo.class;
        System.out.println(clazz.getName());
        
        // 字符串常量池（JDK7后移到堆中）
        String s1 = "hello";  // 常量池
        String s2 = "hello";  // 复用常量池中的
        System.out.println(s1 == s2);  // true
    }
}

// JDK 7 vs JDK 8+ 的变化
// JDK 7:
// ┌─────────────────┐
// │  永久代 PermGen  │
// │  - 类元数据      │
// │  - 静态变量      │
// │  - 常量池        │
// └─────────────────┘

// JDK 8+:
// ┌──────────────────┐
// │  元空间 Metaspace │
// │  (本地内存)       │
// │  - 类元数据       │
// └──────────────────┘
// ┌──────────────────┐
// │  堆 Heap          │
// │  - 静态变量       │
// │  - 字符串常量池   │
// └──────────────────┘

// Metaspace OOM 示例
public class MetaspaceOOM {
    public static void main(String[] args) {
        // VM参数：-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
        while (true) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Object.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                public Object intercept(Object obj, Method method, 
                                      Object[] args, MethodProxy proxy) {
                    return proxy.invokeSuper(obj, args);
                }
            });
            enhancer.create();  // 动态生成类
            // 最终抛出 OutOfMemoryError: Metaspace
        }
    }
}`
			},
			{
				point: '直接内存（Direct Memory）：不是JVM运行时数据区的一部分，通过NIO的ByteBuffer.allocateDirect()分配。',
				code: `import java.nio.ByteBuffer;

// 直接内存示例
public class DirectMemoryDemo {
    public static void main(String[] args) {
        // 堆内存分配（使用JVM堆）
        ByteBuffer heapBuffer = ByteBuffer.allocate(1024);
        
        // 直接内存分配（使用操作系统内存）
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
        
        // 直接内存的优势：减少数据复制
        // 堆内存读写流程：
        // 1. 应用 -> JVM堆
        // 2. JVM堆 -> 系统内存
        // 3. 系统内存 -> I/O设备
        
        // 直接内存读写流程：
        // 1. 应用 -> 系统内存
        // 2. 系统内存 -> I/O设备
        
        // 性能测试
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            heapBuffer.putInt(i);
            heapBuffer.flip();
            heapBuffer.clear();
        }
        System.out.println("堆内存耗时: " + 
            (System.currentTimeMillis() - start) + "ms");
        
        start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            directBuffer.putInt(i);
            directBuffer.flip();
            directBuffer.clear();
        }
        System.out.println("直接内存耗时: " + 
            (System.currentTimeMillis() - start) + "ms");
    }
}

// DirectMemory OOM
public class DirectMemoryOOM {
    public static void main(String[] args) {
        // VM参数：-XX:MaxDirectMemorySize=10M
        List<ByteBuffer> list = new ArrayList<>();
        while (true) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 1024);
            list.add(buffer);
            System.out.println("分配1MB直接内存");
            // 最终抛出 OutOfMemoryError: Direct buffer memory
        }
    }
}`
			}
		]
	},
	{
		id: 27,
		title: '垃圾回收机制',
		description: 'GC算法、分代收集、常见垃圾收集器，优化Java程序性能的关键技术。',
		icon: '♻️',
		categoryId: 'jvm',
		categoryName: 'Java内存模型与JVM',
		categoryIcon: '💻',
		difficulty: '高级',
		color: 'linear-gradient(135deg, #d299c2 0%, #fef9d7 100%)',
		headerBg: 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)',
		tagBg: 'linear-gradient(135deg, #34495e 0%, #2c3e50 100%)',
		tagColor: '#ffffff',
		difficultyBg: 'linear-gradient(135deg, #c0392b 0%, #8e44ad 100%)',
		keyPoints: [
			{
				point: 'GC Root判断对象是否可回收，包括虚拟机栈、方法区静态变量、常量、JNI引用等。',
				code: `// GC Root 示例
public class GCRootDemo {
    // 1. 方法区中的静态变量 - GC Root
    private static Object staticObj = new Object();
    
    // 2. 方法区中的常量 - GC Root
    private static final Object CONSTANT = new Object();
    
    public void method() {
        // 3. 虚拟机栈中的局部变量 - GC Root
        Object localObj = new Object();
        
        // 4. 这个对象没有GC Root引用，可被回收
        Object temp = new Object();
        temp = null;  // 不再有引用，可被GC
        
        // 5. 引用链
        Object obj1 = new Object();
        Object obj2 = obj1;  // obj2引用obj1
        obj1 = null;         // obj1置空
        // obj2仍是GC Root，所以对象不会被回收
    }
    
    public static void main(String[] args) {
        new GCRootDemo().method();
        System.gc();
    }
}

// 可达性分析示例
/*
GC Root 示意图：
    [GC Root]
       ↓
    [对象A] → [对象B] → [对象C]
                         ↓
                      [对象D]
    
    [对象E] → [对象F]  ← 没有GC Root引用，可被回收
*/`
			},
			{
				point: 'GC算法：标记-清除（产生碎片）、复制（空间浪费）、标记-整理（效率低），各有优缺点。',
				code: `// GC算法原理示意
public class GCAlgorithm {
    
    // 1. 标记-清除算法（Mark-Sweep）
    /*
    优点：简单
    缺点：产生内存碎片
    
    标记阶段：
    [对象A][对象B][对象C][对象D][对象E]
     (活)  (死)  (活)  (死)  (活)
    
    清除阶段：
    [对象A][空闲][对象C][空闲][对象E]
            ↑碎片       ↑碎片
    */
    
    // 2. 复制算法（Copying）
    /*
    优点：无碎片，效率高
    缺点：浪费50%空间
    
    Eden区 (8)         Survivor0 (1)    Survivor1 (1)
    [A][B][C][D][E] →  [A][C][E]        [空]
     活 死 活 死 活
    */
    public void copyingDemo() {
        // 新生代使用复制算法
        // Eden:Survivor0:Survivor1 = 8:1:1
        // Minor GC时，Eden和一个Survivor中的存活对象
        // 复制到另一个Survivor
    }
    
    // 3. 标记-整理算法（Mark-Compact）
    /*
    优点：无碎片
    缺点：效率较低（需要移动对象）
    
    标记阶段：
    [对象A][对象B][对象C][对象D][对象E]
     (活)  (死)  (活)  (死)  (活)
    
    整理阶段：
    [对象A][对象C][对象E][空闲空间]
    */
    public void compactDemo() {
        // 老年代使用标记-整理算法
        // 存活率高，不适合复制算法
    }
}

// 分代收集策略
public class GenerationalGC {
    public static void main(String[] args) {
        // 新生代：对象存活率低，使用复制算法
        for (int i = 0; i < 1000000; i++) {
            byte[] temp = new byte[1024];  // 临时对象，很快被回收
        }
        
        // 老年代：对象存活率高，使用标记-整理算法
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(new byte[1024 * 1024]);  // 长期存活的对象
        }
    }
}`
			},
			{
				point: '分代收集：新生代（Eden+Survivor）使用复制算法，老年代使用标记-整理算法，提高GC效率。',
				code: `// 分代收集示例
public class GenerationalCollection {
    public static void main(String[] args) {
        // 对象分配流程：
        // 1. 优先在Eden区分配
        byte[] obj1 = new byte[1024 * 1024];  // 1MB，分配到Eden
        
        // 2. Eden区满时触发Minor GC
        for (int i = 0; i < 10; i++) {
            byte[] temp = new byte[1024 * 1024];
            // Eden满 -> Minor GC -> 存活对象 -> Survivor
        }
        
        // 3. 大对象直接进入老年代
        // VM参数：-XX:PretenureSizeThreshold=3145728 (3MB)
        byte[] bigObj = new byte[4 * 1024 * 1024];  // 4MB，直接到老年代
        
        // 4. 长期存活对象进入老年代
        // 对象年龄（Age）达到阈值（默认15）后晋升到老年代
        
        // 5. 动态年龄判定
        // Survivor中相同年龄对象大小总和 > Survivor空间一半
        // 则年龄 >= 该年龄的对象直接进入老年代
    }
}

// 对象晋升过程
/*
┌─────────────────────────────────────┐
│           新生代 (Young)             │
│  ┌──────────┬────────┬────────┐    │
│  │  Eden    │  S0    │  S1    │    │
│  │          │        │        │    │
│  │ 新对象   │ 存活1次│ 存活2次│    │
│  └──────────┴────────┴────────┘    │
│       ↓ Minor GC                    │
│       ↓ 年龄+1                      │
│       ↓ 年龄达到15 ──────────┐      │
└────────────────────────────┼──────┘
                             │
                             ↓
┌────────────────────────────┼──────┐
│         老年代 (Old)       │      │
│                            │      │
│         长期存活对象  ←────┘      │
│                                   │
│       ↓ Full GC                   │
└───────────────────────────────────┘
*/

// Minor GC vs Full GC
public class GCTypes {
    public static void main(String[] args) {
        // Minor GC：新生代GC，频繁但快
        // - 触发条件：Eden区满
        // - 回收区域：新生代
        // - 特点：快速，STW时间短
        
        // Major GC / Full GC：老年代GC，慢但不频繁
        // - 触发条件：老年代满、元空间满、System.gc()
        // - 回收区域：老年代 或 整个堆+元空间
        // - 特点：慢，STW时间长
        
        // 查看GC日志（VM参数：-XX:+PrintGCDetails）
        System.gc();  // 建议Full GC
    }
}`
			},
			{
				point: '常见垃圾收集器：Serial、Parallel、CMS、G1、ZGC，根据应用特点选择合适的GC。',
				code: `// 垃圾收集器选择
public class GCCollectors {
    /*
    1. Serial GC（串行）
    - 参数：-XX:+UseSerialGC
    - 特点：单线程，STW
    - 适用：客户端模式，单核CPU
    */
    
    /*
    2. Parallel GC（并行，吞吐量优先）
    - 参数：-XX:+UseParallelGC
    - 特点：多线程，STW，关注吞吐量
    - 适用：后台计算任务，科学计算
    */
    
    /*
    3. CMS（Concurrent Mark Sweep，低延迟）
    - 参数：-XX:+UseConcMarkSweepGC
    - 特点：并发标记和清除，减少STW
    - 缺点：产生碎片，CPU资源敏感
    - 适用：互联网应用，Web服务
    
    CMS工作流程：
    1. 初始标记（STW）     - 快
    2. 并发标记           - 慢，但不STW
    3. 重新标记（STW）     - 较快
    4. 并发清除           - 慢，但不STW
    */
    
    /*
    4. G1（Garbage First，JDK 9+默认）
    - 参数：-XX:+UseG1GC
    - 特点：分区收集，可预测停顿
    - 适用：大堆内存（>4GB），低延迟要求
    */
    
    public static void main(String[] args) {
        // G1 GC 参数配置
        /*
        -XX:+UseG1GC                      // 使用G1
        -XX:MaxGCPauseMillis=200          // 最大停顿时间200ms
        -XX:G1HeapRegionSize=4m           // Region大小
        -XX:InitiatingHeapOccupancyPercent=45  // 堆占用45%触发GC
        */
        
        // CMS 参数配置
        /*
        -XX:+UseConcMarkSweepGC           // 使用CMS
        -XX:+UseCMSInitiatingOccupancyOnly // 只使用占用率触发
        -XX:CMSInitiatingOccupancyFraction=70  // 老年代70%触发
        -XX:+CMSScavengeBeforeRemark      // Remark前Minor GC
        */
    }
}

// GC日志分析示例
/*
[GC (Allocation Failure) 
 [PSYoungGen: 65536K->10736K(76288K)] 
 65536K->10744K(251392K), 0.0123456 secs]
 
解释：
- Allocation Failure: 分配失败触发GC
- PSYoungGen: 新生代
- 65536K->10736K: 新生代GC前后大小
- (76288K): 新生代总大小
- 65536K->10744K: 堆GC前后大小
- (251392K): 堆总大小
- 0.0123456 secs: GC耗时
*/`
			},
			{
				point: '引用类型：强引用、软引用、弱引用、虚引用，控制对象的回收时机。',
				code: `import java.lang.ref.*;
import java.util.*;

// 四种引用类型
public class ReferenceTypes {
    public static void main(String[] args) {
        // 1. 强引用（Strong Reference）- 永不回收
        Object strongRef = new Object();
        // 只要strongRef存在，对象永不被GC
        
        // 2. 软引用（Soft Reference）- 内存不足时回收
        SoftReference<byte[]> softRef = new SoftReference<>(new byte[1024 * 1024]);
        System.out.println("软引用: " + softRef.get());
        System.gc();
        System.out.println("GC后: " + softRef.get());  // 可能还在
        // 只有内存不足时才回收
        
        // 3. 弱引用（Weak Reference）- GC时回收
        WeakReference<byte[]> weakRef = new WeakReference<>(new byte[1024]);
        System.out.println("弱引用: " + weakRef.get());
        System.gc();
        System.out.println("GC后: " + weakRef.get());  // null，已被回收
        
        // 4. 虚引用（Phantom Reference）- 无法通过引用获取对象
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        PhantomReference<byte[]> phantomRef = 
            new PhantomReference<>(new byte[1024], queue);
        System.out.println("虚引用: " + phantomRef.get());  // 总是null
        // 用于对象回收跟踪
    }
}

// 软引用的应用：图片缓存
public class ImageCache {
    private Map<String, SoftReference<byte[]>> cache = new HashMap<>();
    
    public byte[] getImage(String path) {
        SoftReference<byte[]> ref = cache.get(path);
        if (ref != null) {
            byte[] image = ref.get();
            if (image != null) {
                return image;  // 缓存命中
            }
        }
        
        // 缓存未命中，加载图片
        byte[] image = loadImage(path);
        cache.put(path, new SoftReference<>(image));
        return image;
    }
    
    private byte[] loadImage(String path) {
        // 从磁盘加载图片
        return new byte[1024 * 1024];
    }
}

// 弱引用的应用：ThreadLocal
public class ThreadLocalDemo {
    // ThreadLocalMap的Entry是弱引用
    static class Entry extends WeakReference<ThreadLocal<?>> {
        Object value;
        
        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            value = v;
        }
    }
    
    // ThreadLocal被置null后，Entry的key会被GC
    // 但value还在，可能导致内存泄漏
    // 所以要手动remove()
}

// 引用队列应用
public class ReferenceQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        WeakReference<byte[]> ref = new WeakReference<>(
            new byte[1024], queue);
        
        System.out.println("对象: " + ref.get());
        System.gc();
        Thread.sleep(100);
        
        System.out.println("GC后: " + ref.get());
        
        // 检查引用队列
        Reference<? extends byte[]> polled = queue.poll();
        if (polled != null) {
            System.out.println("对象已被回收");
        }
    }
}`
			}
		]
	},
	{
		id: 28,
		title: '类加载机制',
		description: '类加载过程、类加载器、双亲委派模型，理解类的生命周期和加载机制。',
		icon: '📚',
		categoryId: 'jvm',
		categoryName: 'Java内存模型与JVM',
		categoryIcon: '💻',
		difficulty: '高级',
		color: 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
		headerBg: 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)',
		tagBg: 'linear-gradient(135deg, #34495e 0%, #2c3e50 100%)',
		tagColor: '#ffffff',
		difficultyBg: 'linear-gradient(135deg, #c0392b 0%, #8e44ad 100%)',
		keyPoints: [
			{
				point: '类加载过程包括：加载、验证、准备、解析、初始化五个阶段。',
				code: `// 类加载过程示例
public class ClassLoadingDemo {
    // 准备阶段：staticVar = 0（默认值）
    // 初始化阶段：staticVar = 100（赋值）
    private static int staticVar = 100;
    
    // 准备阶段：count = 0
    // 初始化阶段：先执行static块，count = 1，再执行赋值，count = 2
    private static int count = 2;
    static {
        count = 1;
    }
    
    public static void main(String[] args) {
        System.out.println(count);  // 输出 2
    }
}

/*
类加载完整流程：

1. 加载（Loading）
   - 通过类的全限定名获取二进制字节流
   - 将字节流转化为方法区的运行时数据结构
   - 在内存中生成Class对象

2. 验证（Verification）
   - 文件格式验证（魔数、版本号）
   - 元数据验证（语义分析）
   - 字节码验证（数据流分析）
   - 符号引用验证

3. 准备（Preparation）
   - 为类变量分配内存
   - 设置零值（不是初始值！）
   - final static常量直接赋值

4. 解析（Resolution）
   - 符号引用 -> 直接引用
   - 类、接口、字段、方法的解析

5. 初始化（Initialization）
   - 执行<clinit>()方法
   - 为类变量赋初始值
   - 执行静态代码块
*/

// 类初始化时机
public class InitializationTiming {
    static class Parent {
        static {
            System.out.println("Parent初始化");
        }
        public static int value = 100;
    }
    
    static class Child extends Parent {
        static {
            System.out.println("Child初始化");
        }
    }
    
    public static void main(String[] args) {
        // 1. 主动引用，会触发初始化
        System.out.println(Child.value);  
        // 输出：Parent初始化（不会初始化Child）
        
        // 2. 被动引用，不会触发初始化
        Parent[] arr = new Parent[10];  // 不会初始化Parent
        System.out.println(Parent.value);  // 常量不会初始化
    }
}`
			},
			{
				point: '三种类加载器：启动类加载器（Bootstrap）、扩展类加载器（Extension）、应用程序类加载器（Application）。',
				code: `// 类加载器示例
public class ClassLoaderDemo {
    public static void main(String[] args) {
        // 1. 启动类加载器（Bootstrap ClassLoader）
        // 加载<JAVA_HOME>/lib目录的类（如rt.jar）
        // C++实现，Java中无法直接获取
        ClassLoader bootstrapLoader = String.class.getClassLoader();
        System.out.println("String的类加载器: " + bootstrapLoader);  // null
        
        // 2. 扩展类加载器（Extension ClassLoader）
        // 加载<JAVA_HOME>/lib/ext目录的类
        ClassLoader extLoader = sun.security.ec.ECKeyFactory.class.getClassLoader();
        System.out.println("扩展类加载器: " + extLoader);
        // sun.misc.Launcher$ExtClassLoader
        
        // 3. 应用程序类加载器（Application ClassLoader）
        // 加载classpath上的类
        ClassLoader appLoader = ClassLoaderDemo.class.getClassLoader();
        System.out.println("应用程序类加载器: " + appLoader);
        // sun.misc.Launcher$AppClassLoader
        
        // 获取类加载器层次
        ClassLoader current = ClassLoaderDemo.class.getClassLoader();
        while (current != null) {
            System.out.println(current);
            current = current.getParent();
        }
        /*
        输出：
        sun.misc.Launcher$AppClassLoader@xxx
        sun.misc.Launcher$ExtClassLoader@xxx
        */
    }
}

// 类加载器层次结构
/*
┌──────────────────────────┐
│  Bootstrap ClassLoader   │  ← C++实现，Java获取为null
│  (<JAVA_HOME>/lib)       │
└────────────┬─────────────┘
             ↑ parent
┌────────────┴─────────────┐
│  Extension ClassLoader   │
│  (<JAVA_HOME>/lib/ext)   │
└────────────┬─────────────┘
             ↑ parent
┌────────────┴─────────────┐
│  Application ClassLoader │
│  (classpath)             │
└────────────┬─────────────┘
             ↑ parent
┌────────────┴─────────────┐
│  User ClassLoader        │  ← 自定义类加载器
└──────────────────────────┘
*/`
			},
			{
				point: '双亲委派模型：类加载请求先委托给父加载器，保证Java核心类库的安全性。',
				code: `// 双亲委派模型原理
public abstract class ClassLoader {
    protected Class<?> loadClass(String name, boolean resolve)
            throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // 1. 检查类是否已加载
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        // 2. 委托给父加载器
                        c = parent.loadClass(name, false);
                    } else {
                        // 3. 父加载器为null，使用启动类加载器
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 父加载器无法加载
                }
                
                if (c == null) {
                    // 4. 父加载器无法加载，自己尝试加载
                    c = findClass(name);
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
}

// 双亲委派的好处
public class ParentalDelegationDemo {
    /*
    示例：加载java.lang.String类
    
    Application ClassLoader
      → 委托 Extension ClassLoader
        → 委托 Bootstrap ClassLoader
          → Bootstrap加载成功！
    
    如果没有双亲委派：
    - 用户可以自定义java.lang.String
    - 破坏Java核心类库的安全性
    */
    
    public static void main(String[] args) throws Exception {
        // 尝试自定义String（会失败）
        MyClassLoader loader = new MyClassLoader();
        // 由于双亲委派，最终还是加载JDK的String
        Class<?> clazz = loader.loadClass("java.lang.String");
        System.out.println(clazz.getClassLoader());  // null (Bootstrap)
    }
}

// 打破双亲委派模型的场景
public class BreakParentalDelegation {
    /*
    1. JDK 1.2之前（没有双亲委派）
    
    2. SPI（Service Provider Interface）
       - JDBC驱动加载
       - 启动类加载器加载JDBC接口
       - 但驱动实现在classpath，需要应用类加载器
       - 使用线程上下文类加载器解决
    */
    
    public static void main(String[] args) throws Exception {
        // JDBC示例
        // DriverManager由启动类加载器加载
        // MySQL Driver由应用类加载器加载
        Class.forName("com.mysql.jdbc.Driver");
        
        // 使用线程上下文类加载器
        ClassLoader contextLoader = Thread.currentThread()
            .getContextClassLoader();
        System.out.println(contextLoader);
    }
    
    /*
    3. OSGi（动态模块化）
       - 每个模块有自己的类加载器
       - 平级委托，不是双亲委派
    
    4. Tomcat
       - WebappClassLoader打破双亲委派
       - 优先加载WEB-INF/classes和WEB-INF/lib
       - 实现应用隔离
    */
}`
			},
			{
				point: '自定义类加载器：继承ClassLoader，重写findClass方法，实现特殊的类加载需求。',
				code: `import java.io.*;

// 自定义类加载器
public class MyClassLoader extends ClassLoader {
    private String classPath;
    
    public MyClassLoader(String classPath) {
        this.classPath = classPath;
    }
    
    // 重写findClass方法（推荐）
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            // 1. 读取class文件的字节码
            byte[] classData = loadClassData(name);
            if (classData == null) {
                throw new ClassNotFoundException();
            }
            
            // 2. 调用defineClass将字节码转为Class对象
            return defineClass(name, classData, 0, classData.length);
        } catch (IOException e) {
            throw new ClassNotFoundException(name, e);
        }
    }
    
    // 从文件系统加载class文件
    private byte[] loadClassData(String className) throws IOException {
        String fileName = classPath + File.separator +
            className.replace('.', File.separatorChar) + ".class";
        
        try (FileInputStream fis = new FileInputStream(fileName);
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            return baos.toByteArray();
        }
    }
    
    public static void main(String[] args) throws Exception {
        // 使用自定义类加载器
        MyClassLoader loader = new MyClassLoader("/custom/path");
        Class<?> clazz = loader.loadClass("com.example.MyClass");
        
        Object instance = clazz.newInstance();
        System.out.println("类加载器: " + clazz.getClassLoader());
    }
}

// 加密类加载器示例
public class EncryptClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            // 1. 读取加密的class文件
            byte[] encryptedData = readEncryptedFile(name);
            
            // 2. 解密
            byte[] decryptedData = decrypt(encryptedData);
            
            // 3. 加载类
            return defineClass(name, decryptedData, 0, decryptedData.length);
        } catch (Exception e) {
            throw new ClassNotFoundException(name, e);
        }
    }
    
    private byte[] readEncryptedFile(String name) {
        // 读取加密文件
        return null;
    }
    
    private byte[] decrypt(byte[] data) {
        // 解密算法
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) (data[i] ^ 0xFF);  // 简单异或解密
        }
        return data;
    }
}

// 热部署类加载器
public class HotSwapClassLoader extends ClassLoader {
    public Class<?> loadClass(String name, boolean resolve) 
            throws ClassNotFoundException {
        // 不使用缓存，每次都重新加载
        // 实现类的热替换
        synchronized (getClassLoadingLock(name)) {
            Class<?> c = findClass(name);
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
}`
			},
			{
				point: '类的初始化顺序：父类静态 → 子类静态 → 父类实例 → 父类构造 → 子类实例 → 子类构造。',
				code: `// 类初始化顺序示例
class Parent {
    // 1. 父类静态变量
    private static int staticVar = getStaticVar();
    
    // 2. 父类静态代码块
    static {
        System.out.println("1. Parent静态代码块");
    }
    
    // 3. 父类实例变量
    private int instanceVar = getInstanceVar();
    
    // 4. 父类实例代码块
    {
        System.out.println("3. Parent实例代码块");
    }
    
    // 5. 父类构造方法
    public Parent() {
        System.out.println("4. Parent构造方法");
    }
    
    private static int getStaticVar() {
        System.out.println("0. Parent静态变量初始化");
        return 1;
    }
    
    private int getInstanceVar() {
        System.out.println("2. Parent实例变量初始化");
        return 1;
    }
}

class Child extends Parent {
    // 6. 子类静态变量
    private static int staticVar = getStaticVar();
    
    // 7. 子类静态代码块
    static {
        System.out.println("5. Child静态代码块");
    }
    
    // 8. 子类实例变量
    private int instanceVar = getInstanceVar();
    
    // 9. 子类实例代码块
    {
        System.out.println("7. Child实例代码块");
    }
    
    // 10. 子类构造方法
    public Child() {
        System.out.println("8. Child构造方法");
    }
    
    private static int getStaticVar() {
        System.out.println("4. Child静态变量初始化");
        return 1;
    }
    
    private int getInstanceVar() {
        System.out.println("6. Child实例变量初始化");
        return 1;
    }
}

public class InitializationOrder {
    public static void main(String[] args) {
        System.out.println("=== 开始创建Child对象 ===");
        Child child = new Child();
        System.out.println("=== Child对象创建完成 ===");
    }
}

/*
输出结果：
=== 开始创建Child对象 ===
0. Parent静态变量初始化
1. Parent静态代码块
4. Child静态变量初始化
5. Child静态代码块
2. Parent实例变量初始化
3. Parent实例代码块
4. Parent构造方法
6. Child实例变量初始化
7. Child实例代码块
8. Child构造方法
=== Child对象创建完成 ===

总结：
1. 静态部分：父类 → 子类
2. 实例部分：父类 → 子类
3. 同一类中：变量 → 代码块 → 构造方法
*/`
			}
		]
	},
	{
		id: 29,
		title: 'JVM性能调优',
		description: 'JVM参数配置、性能监控工具、内存泄漏排查，提升应用性能的关键技能。',
		icon: '⚡',
		categoryId: 'jvm',
		categoryName: 'Java内存模型与JVM',
		categoryIcon: '💻',
		difficulty: '高级',
		color: 'linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%)',
		headerBg: 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)',
		tagBg: 'linear-gradient(135deg, #34495e 0%, #2c3e50 100%)',
		tagColor: '#ffffff',
		difficultyBg: 'linear-gradient(135deg, #c0392b 0%, #8e44ad 100%)',
		keyPoints: [
			{
				point: 'JVM内存参数配置：-Xms初始堆、-Xmx最大堆、-Xmn新生代、-Xss栈大小等。',
				code: `// JVM内存参数配置
/*
启动命令示例：
java -Xms2g              // 初始堆大小2GB
     -Xmx4g              // 最大堆大小4GB
     -Xmn1g              // 新生代大小1GB
     -Xss256k            // 每个线程栈大小256KB
     -XX:MetaspaceSize=256m      // 元空间初始大小
     -XX:MaxMetaspaceSize=512m   // 元空间最大大小
     -XX:MaxDirectMemorySize=1g  // 直接内存最大值
     -jar myapp.jar

常用内存参数：
1. -Xms: 初始堆大小（建议与-Xmx相同，避免动态扩容）
2. -Xmx: 最大堆大小（一般设置为物理内存的70-80%）
3. -Xmn: 新生代大小（一般为堆的1/3到1/4）
4. -XX:SurvivorRatio=8: Eden:Survivor = 8:1:1
5. -XX:NewRatio=2: 老年代:新生代 = 2:1
*/

// 查看JVM参数
public class JVMParameters {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        
        long maxMemory = runtime.maxMemory();   // -Xmx
        long totalMemory = runtime.totalMemory(); // 当前堆大小
        long freeMemory = runtime.freeMemory();  // 空闲内存
        
        System.out.println("最大内存: " + (maxMemory / 1024 / 1024) + "MB");
        System.out.println("总内存: " + (totalMemory / 1024 / 1024) + "MB");
        System.out.println("空闲内存: " + (freeMemory / 1024 / 1024) + "MB");
        System.out.println("已用内存: " + 
            ((totalMemory - freeMemory) / 1024 / 1024) + "MB");
    }
}`
			},
			{
				point: 'GC参数配置：选择垃圾收集器、配置GC日志、调整GC策略等。',
				code: `// GC参数配置
/*
1. 选择垃圾收集器
-XX:+UseSerialGC           // Serial GC
-XX:+UseParallelGC         // Parallel GC（吞吐量优先）
-XX:+UseConcMarkSweepGC    // CMS（低延迟）
-XX:+UseG1GC               // G1 GC（JDK 9+默认）
-XX:+UseZGC                // ZGC（JDK 11+，超低延迟）

2. GC日志配置（JDK 8）
-XX:+PrintGC                      // 打印GC信息
-XX:+PrintGCDetails               // 打印详细GC信息
-XX:+PrintGCTimeStamps            // 打印GC时间戳
-XX:+PrintGCDateStamps            // 打印GC日期时间
-Xloggc:/path/to/gc.log          // GC日志文件路径
-XX:+PrintHeapAtGC                // 打印GC前后堆信息
-XX:+PrintGCApplicationStoppedTime // 打印STW时间

3. GC日志配置（JDK 9+）
-Xlog:gc*:file=/path/to/gc.log:time,level,tags

4. CMS参数
-XX:+UseCMSInitiatingOccupancyOnly     // 只根据占用率触发
-XX:CMSInitiatingOccupancyFraction=70  // 老年代70%触发CMS
-XX:+CMSScavengeBeforeRemark           // Remark前进行Minor GC
-XX:+UseCMSCompactAtFullCollection     // Full GC后压缩
-XX:CMSFullGCsBeforeCompaction=0       // 多少次Full GC后压缩

5. G1参数
-XX:MaxGCPauseMillis=200               // 最大停顿时间200ms
-XX:G1HeapRegionSize=4m                // Region大小
-XX:InitiatingHeapOccupancyPercent=45  // 堆占用45%触发并发标记
-XX:G1NewSizePercent=5                 // 新生代最小比例
-XX:G1MaxNewSizePercent=60             // 新生代最大比例
-XX:ConcGCThreads=2                    // 并发GC线程数
*/

// GC日志分析示例
/*
[GC (Allocation Failure) [PSYoungGen: 33280K->5088K(38400K)] 
33280K->5096K(125952K), 0.0048975 secs] 
[Times: user=0.01 sys=0.00, real=0.01 secs]

解析：
- Allocation Failure: Eden区分配失败触发Minor GC
- PSYoungGen: 使用Parallel Scavenge新生代收集器
- 33280K->5088K: 新生代GC前后大小
- (38400K): 新生代总大小
- 33280K->5096K: 整个堆GC前后大小
- (125952K): 堆总大小
- 0.0048975 secs: GC耗时
- user: 用户态CPU时间
- sys: 内核态CPU时间
- real: 实际耗时
*/`
			},
			{
				point: 'JVM监控工具：jstat监控GC、jmap导出堆、jstack查看线程、jinfo查看参数等。',
				code: `// JVM监控工具使用
/*
1. jps - 查看Java进程
命令：jps -l
输出：12345 com.example.MyApp

2. jstat - 监控GC和类加载
jstat -gc <pid> 1000 10    // 每秒输出一次，共10次
jstat -gcutil <pid>         // GC统计（百分比）
jstat -gccause <pid>        // GC原因

输出示例：
S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU
8192.0 8192.0  0.0   1024.0  65536.0  12345.0  87380.0    23456.0  21248.0 20512.0

解释：
S0C/S1C: Survivor0/1容量
S0U/S1U: Survivor0/1使用量
EC: Eden容量
EU: Eden使用量
OC: 老年代容量
OU: 老年代使用量
MC: 元空间容量
MU: 元空间使用量

3. jmap - 堆转储和内存分析
jmap -heap <pid>                   // 查看堆配置和使用情况
jmap -histo <pid>                  // 查看对象统计
jmap -histo:live <pid>             // 触发Full GC后查看
jmap -dump:live,format=b,file=heap.bin <pid>  // 导出堆转储

4. jstack - 线程栈快照
jstack <pid>                       // 查看所有线程栈
jstack <pid> > thread.txt          // 导出到文件
jstack -l <pid>                    // 查看锁信息

5. jinfo - 查看和修改JVM参数
jinfo <pid>                        // 查看所有参数
jinfo -flag PrintGC <pid>          // 查看具体参数
jinfo -flag +PrintGC <pid>         // 动态开启参数
*/

// 使用代码获取JVM信息
import java.lang.management.*;
import java.util.*;

public class JVMMonitor {
    public static void main(String[] args) {
        // 1. 内存信息
        MemoryMXBean memoryMBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapUsage = memoryMBean.getHeapMemoryUsage();
        System.out.println("堆内存使用: " + 
            heapUsage.getUsed() / 1024 / 1024 + "MB / " +
            heapUsage.getMax() / 1024 / 1024 + "MB");
        
        // 2. GC信息
        List<GarbageCollectorMXBean> gcBeans = 
            ManagementFactory.getGarbageCollectorMXBeans();
        for (GarbageCollectorMXBean gcBean : gcBeans) {
            System.out.println("GC名称: " + gcBean.getName());
            System.out.println("GC次数: " + gcBean.getCollectionCount());
            System.out.println("GC耗时: " + gcBean.getCollectionTime() + "ms");
        }
        
        // 3. 线程信息
        ThreadMXBean threadMBean = ManagementFactory.getThreadMXBean();
        System.out.println("线程数: " + threadMBean.getThreadCount());
        System.out.println("峰值线程数: " + threadMBean.getPeakThreadCount());
        
        // 4. 类加载信息
        ClassLoadingMXBean classLoadingMBean = 
            ManagementFactory.getClassLoadingMXBean();
        System.out.println("已加载类数: " + 
            classLoadingMBean.getLoadedClassCount());
    }
}`
			},
			{
				point: '内存泄漏排查：使用jmap导出堆、MAT分析、找到泄漏对象、定位代码位置。',
				code: `// 内存泄漏示例和排查
public class MemoryLeakDemo {
    // 常见内存泄漏场景1：静态集合
    private static List<Object> list = new ArrayList<>();
    
    public void leak1() {
        list.add(new byte[1024 * 1024]);  // 永不释放
    }
    
    // 常见内存泄漏场景2：未关闭资源
    public void leak2() throws Exception {
        FileInputStream fis = new FileInputStream("file.txt");
        // 忘记关闭，导致文件句柄泄漏
    }
    
    // 常见内存泄漏场景3：ThreadLocal未清理
    private static ThreadLocal<byte[]> threadLocal = new ThreadLocal<>();
    
    public void leak3() {
        threadLocal.set(new byte[1024 * 1024]);
        // 线程池中，线程不销毁，ThreadLocal不清理
    }
    
    // 常见内存泄漏场景4：监听器未移除
    public void leak4() {
        Button button = new Button();
        button.addListener(event -> {
            // 匿名内部类持有外部类引用
            System.out.println(this);
        });
        // 按钮销毁了，但监听器还在
    }
}

/*
内存泄漏排查步骤：

1. 发现问题
   - 监控发现内存持续增长
   - 最终触发Full GC或OOM

2. 导出堆转储
   jmap -dump:live,format=b,file=heap.bin <pid>
   
   或配置JVM参数自动导出：
   -XX:+HeapDumpOnOutOfMemoryError
   -XX:HeapDumpPath=/path/to/dump

3. 使用MAT（Memory Analyzer Tool）分析
   - Histogram: 查看对象数量和大小
   - Dominator Tree: 查看对象占用内存
   - Leak Suspects: 自动检测泄漏
   - Path to GC Roots: 查看引用链

4. 定位问题
   - 找到占用内存最大的对象
   - 查看GC Root引用链
   - 定位到具体代码位置
   - 分析为什么无法释放

5. 修复
   - 移除不必要的引用
   - 及时清理资源
   - 使用弱引用/软引用
   - 限制缓存大小
*/

// 正确的写法
public class MemoryLeakFix {
    // 1. 使用弱引用
    private WeakHashMap<Object, Object> cache = new WeakHashMap<>();
    
    // 2. 限制大小
    private Map<String, Object> cache2 = new LinkedHashMap<String, Object>(16, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
            return size() > 1000;  // 最多1000个
        }
    };
    
    // 3. try-with-resources
    public void fix2() throws Exception {
        try (FileInputStream fis = new FileInputStream("file.txt")) {
            // 自动关闭
        }
    }
    
    // 4. ThreadLocal清理
    public void fix3() {
        try {
            threadLocal.set(new byte[1024]);
            // 使用
        } finally {
            threadLocal.remove();  // 清理
        }
    }
}`
			},
			{
				point: '性能调优实践：根据应用特点选择GC、合理设置参数、监控分析、持续优化。',
				code: `// JVM调优实践
public class PerformanceTuning {
    /*
    调优思路：
    
    1. 明确目标
       - 吞吐量优先：Parallel GC
       - 延迟优先：CMS/G1/ZGC
       - 内存占用优先：Serial GC
    
    2. 监控分析
       - GC频率和耗时
       - 内存使用情况
       - CPU使用率
       - 应用响应时间
    
    3. 参数调优
       - 堆大小设置
       - 新生代/老年代比例
       - GC策略选择
       - 线程数配置
    
    4. 验证效果
       - 压力测试
       - 对比调优前后
       - 持续监控
    */
    
    // 示例1：吞吐量优先（后台计算任务）
    /*
    java -Xms4g -Xmx4g 
         -XX:+UseParallelGC 
         -XX:ParallelGCThreads=8 
         -XX:+UseAdaptiveSizePolicy 
         -jar batch-job.jar
    
    特点：
    - 使用Parallel GC
    - 关注吞吐量，STW时间可以接受
    - 自适应调整新生代大小
    */
    
    // 示例2：低延迟优先（Web应用）
    /*
    java -Xms4g -Xmx4g 
         -XX:+UseG1GC 
         -XX:MaxGCPauseMillis=200 
         -XX:G1HeapRegionSize=8m 
         -XX:InitiatingHeapOccupancyPercent=45 
         -XX:+ParallelRefProcEnabled 
         -jar web-app.jar
    
    特点：
    - 使用G1 GC
    - 目标STW时间200ms
    - Region大小8MB
    - 堆占用45%触发并发标记
    - 并行处理Reference
    */
    
    // 示例3：大堆内存应用
    /*
    java -Xms16g -Xmx16g 
         -XX:+UseG1GC 
         -XX:MaxGCPauseMillis=100 
         -XX:G1HeapRegionSize=32m 
         -XX:ConcGCThreads=4 
         -XX:ParallelGCThreads=8 
         -jar big-data.jar
    
    特点：
    - 大堆（16GB）
    - 使用G1处理大堆
    - Region大小32MB
    - 4个并发GC线程
    */
    
    // 常见调优参数总结
    /*
    内存参数：
    -Xms: 初始堆
    -Xmx: 最大堆
    -Xmn: 新生代
    -XX:SurvivorRatio: Eden/Survivor比例
    -XX:NewRatio: 老年代/新生代比例
    
    GC参数：
    -XX:+UseG1GC: 使用G1
    -XX:MaxGCPauseMillis: 最大停顿时间
    -XX:ParallelGCThreads: 并行GC线程数
    -XX:ConcGCThreads: 并发GC线程数
    
    其他参数：
    -XX:+HeapDumpOnOutOfMemoryError: OOM时导出堆
    -XX:HeapDumpPath: 堆转储路径
    -XX:+PrintGCDetails: 打印GC详情
    -Xloggc: GC日志路径
    */
}`
			}
		]
	},
	{
		id: 30,
		title: '字节码与JIT',
		description: '理解Java字节码结构、字节码指令、JIT编译优化，深入理解Java运行机制。',
		icon: '🔤',
		categoryId: 'jvm',
		categoryName: 'Java内存模型与JVM',
		categoryIcon: '💻',
		difficulty: '高级',
		color: 'linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%)',
		headerBg: 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)',
		tagBg: 'linear-gradient(135deg, #34495e 0%, #2c3e50 100%)',
		tagColor: '#ffffff',
		difficultyBg: 'linear-gradient(135deg, #c0392b 0%, #8e44ad 100%)',
		keyPoints: [
			{
				point: '字节码文件结构：魔数(CAFEBABE)、版本号、常量池、访问标志、类索引、字段表、方法表、属性表。',
				code: `// 字节码文件结构示例
public class BytecodeStructure {
    private int value = 10;
    
    public int getValue() {
        return value;
    }
}

/*
使用 javap -v BytecodeStructure.class 查看：

Classfile BytecodeStructure.class
  Last modified ...
  MD5 checksum ...
  Compiled from "BytecodeStructure.java"
public class BytecodeStructure
  minor version: 0            // 次版本号
  major version: 52           // 主版本号（52 = JDK 8）
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:              // 常量池
   #1 = Methodref          #3.#15
   #2 = Fieldref           #4.#16
   #3 = Class              #17
   #4 = Class              #18
   ...
{
  private int value;
    descriptor: I
    flags: ACC_PRIVATE
    
  public BytecodeStructure();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1
         4: aload_0
         5: bipush        10
         7: putfield      #2
        10: return
        
  public int getValue();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2
         4: ireturn
}
*/

// 字节码文件结构（16进制）
/*
CA FE BA BE          // 魔数
00 00 00 34          // 版本号（0x34 = 52，JDK 8）
00 13                // 常量池大小
01 00 05             // 常量#1: UTF8
...
*/`
			},
			{
				point: '字节码指令：加载存储(load/store)、运算(add/sub)、类型转换(i2l)、对象操作(new)、方法调用(invoke)等。',
				code: `// 字节码指令示例
public class BytecodeInstructions {
    public int calculate(int a, int b) {
        int sum = a + b;
        return sum;
    }
    
    /*
    对应字节码（javap -c）:
    public int calculate(int, int);
      Code:
         0: iload_1        // 加载局部变量a到操作数栈
         1: iload_2        // 加载局部变量b到操作数栈
         2: iadd           // 弹出栈顶两个int相加
         3: istore_3       // 结果存储到局部变量sum
         4: iload_3        // 加载sum到栈
         5: ireturn        // 返回int值
    */
    
    public void demonstrateInstructions() {
        // 1. 加载指令
        int i = 10;          // bipush 10; istore_1
        long l = 100L;       // ldc2_w #2; lstore_2
        
        // 2. 存储指令
        int[] arr = new int[5];
        arr[0] = 1;          // iconst_1; iastore
        
        // 3. 运算指令
        int result = i + 5;  // iload_1; iconst_5; iadd
        int mul = i * 2;     // iload_1; iconst_2; imul
        
        // 4. 类型转换
        long l2 = i;         // iload_1; i2l
        int i2 = (int) l;    // lload_2; l2i
        
        // 5. 对象创建
        Object obj = new Object();  
        // new #2; dup; invokespecial #1
        
        // 6. 方法调用
        obj.hashCode();      // invokevirtual #3
        Math.max(1, 2);      // invokestatic #4
    }
}

// 方法调用指令
public class InvokeInstructions {
    /*
    1. invokevirtual - 调用实例方法（虚方法表）
    2. invokespecial - 调用构造方法、私有方法、父类方法
    3. invokestatic - 调用静态方法
    4. invokeinterface - 调用接口方法
    5. invokedynamic - 动态调用（Lambda表达式）
    */
    
    public void testInvoke() {
        String s = "hello";
        s.length();              // invokevirtual
        
        super.toString();        // invokespecial
        
        Math.max(1, 2);          // invokestatic
        
        List<String> list = new ArrayList<>();
        list.size();             // invokeinterface
        
        Runnable r = () -> {};   // invokedynamic
    }
}`
			},
			{
				point: 'JIT即时编译：解释执行和编译执行，C1编译器（Client）和C2编译器（Server），分层编译。',
				code: `// JIT编译示例
public class JITCompilation {
    /*
    Java执行模式：
    1. 解释执行：逐行解释字节码
    2. 编译执行：热点代码编译为机器码
    
    JIT编译器：
    - C1（Client Compiler）：快速编译，优化少
    - C2（Server Compiler）：慢速编译，优化多
    - Graal（JDK 10+）：新一代JIT编译器
    */
    
    public static void main(String[] args) {
        // 触发JIT编译（默认阈值：方法调用10000次）
        for (int i = 0; i < 20000; i++) {
            calculate(i);
        }
    }
    
    // 热点方法，会被JIT编译
    public static int calculate(int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += i;
        }
        return sum;
    }
}

// JIT编译参数
/*
-XX:+PrintCompilation          // 打印JIT编译信息
-XX:CompileThreshold=10000     // 编译阈值
-XX:+TieredCompilation         // 分层编译（默认开启）
-XX:TieredStopAtLevel=1        // 只使用C1
-XX:+PrintInlining             // 打印内联信息
-XX:+UnlockDiagnosticVMOptions // 解锁诊断选项
-XX:+PrintInlining             // 打印内联决策
-XX:+PrintCodeCache            // 打印CodeCache信息
*/

// 分层编译（JDK 8+默认）
/*
Level 0: 解释执行
Level 1: C1编译，无profiling
Level 2: C1编译，轻量级profiling
Level 3: C1编译，完整profiling
Level 4: C2编译

执行路径：
0 -> 3 -> 4  // 常规路径
0 -> 2 -> 3 -> 4  // C2编译队列满时
0 -> 1 -> 4  // trivial方法
*/

// 查看JIT编译
public class JITDemo {
    public static void main(String[] args) throws Exception {
        // VM参数：-XX:+PrintCompilation
        for (int i = 0; i < 15000; i++) {
            hotMethod(i);
        }
        
        Thread.sleep(1000);  // 等待编译完成
    }
    
    static int hotMethod(int n) {
        return n * 2 + 1;
    }
}

/*
输出（-XX:+PrintCompilation）:
    155   41       3       JITDemo::hotMethod (6 bytes)
    
解释：
155: 编译发生时间（ms）
41: 编译ID
3: 编译级别（Level 3）
JITDemo::hotMethod: 方法名
(6 bytes): 字节码大小
*/`
			},
			{
				point: 'JIT优化技术：方法内联、逃逸分析、标量替换、栈上分配、锁消除等。',
				code: `// JIT优化技术示例
public class JITOptimization {
    
    // 1. 方法内联（Method Inlining）
    public int calculate(int a, int b) {
        return add(a, b) * 2;  // add方法会被内联
    }
    
    private int add(int x, int y) {
        return x + y;
    }
    
    // 优化后等价于：
    // public int calculate(int a, int b) {
    //     return (a + b) * 2;  // add方法已内联
    // }
    
    // 2. 逃逸分析（Escape Analysis）
    public void escapeAnalysisDemo() {
        // 对象不逃逸（仅在方法内使用）
        Point point = new Point(1, 2);
        int sum = point.x + point.y;  // 可能被优化为栈上分配
    }
    
    static class Point {
        int x, y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    
    // 3. 标量替换（Scalar Replacement）
    public void scalarReplacement() {
        // 原代码
        Point p = new Point(1, 2);
        int sum = p.x + p.y;
        
        // 标量替换后
        // int x = 1;
        // int y = 2;
        // int sum = x + y;
        // 对象被拆分为标量，无需在堆上分配
    }
    
    // 4. 栈上分配（Stack Allocation）
    public void stackAllocation() {
        // 对象不逃逸，可能在栈上分配
        for (int i = 0; i < 1000000; i++) {
            Point p = new Point(i, i);
            // p不逃逸，可能在栈上分配
        }
        // 无GC压力
    }
    
    // 5. 锁消除（Lock Elimination）
    public void lockElimination() {
        // StringBuffer是线程安全的，但这里无并发
        StringBuffer sb = new StringBuffer();
        sb.append("a");  // synchronized方法
        sb.append("b");  // synchronized方法
        // JIT检测到sb不逃逸，消除锁
    }
    
    // 6. 锁粗化（Lock Coarsening）
    public void lockCoarsening() {
        // 原代码：多次加锁
        for (int i = 0; i < 100; i++) {
            synchronized (this) {
                // ...
            }
        }
        
        // 优化后：粗化为一次加锁
        // synchronized (this) {
        //     for (int i = 0; i < 100; i++) {
        //         // ...
        //     }
        // }
    }
}

// 启用/禁用JIT优化参数
/*
-XX:+DoEscapeAnalysis        // 启用逃逸分析（默认）
-XX:-DoEscapeAnalysis        // 禁用逃逸分析

-XX:+EliminateAllocations    // 启用标量替换（默认）
-XX:-EliminateAllocations    // 禁用标量替换

-XX:+EliminateLocks          // 启用锁消除（默认）
-XX:-EliminateLocks          // 禁用锁消除

-XX:MaxInlineSize=35         // 内联方法最大字节码大小
-XX:FreqInlineSize=325       // 热点方法内联大小
*/

// 验证优化效果
public class OptimizationBenchmark {
    public static void main(String[] args) {
        // VM参数：-XX:+PrintCompilation -XX:+PrintInlining
        
        // 测试逃逸分析
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            Point p = new Point(i, i);
            int sum = p.x + p.y;
        }
        System.out.println("耗时: " + (System.currentTimeMillis() - start));
        
        // 对比：对象逃逸
        List<Point> list = new ArrayList<>();
        start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            Point p = new Point(i, i);
            list.add(p);  // 对象逃逸，无法优化
        }
        System.out.println("逃逸耗时: " + (System.currentTimeMillis() - start));
    }
}`
			},
			{
				point: '字节码增强技术：ASM、Javassist、ByteBuddy等，实现AOP、动态代理、监控埋点等功能。',
				code: `// 字节码增强示例
import org.objectweb.asm.*;

// 1. 使用ASM进行字节码增强
public class ASMDemo extends ClassVisitor {
    public ASMDemo(ClassVisitor cv) {
        super(Opcodes.ASM5, cv);
    }
    
    @Override
    public MethodVisitor visitMethod(int access, String name, 
                                     String desc, String signature, 
                                     String[] exceptions) {
        MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
        
        // 为方法添加计时逻辑
        return new MethodVisitor(Opcodes.ASM5, mv) {
            @Override
            public void visitCode() {
                // 方法开始：System.currentTimeMillis()
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, 
                    "java/lang/System", "currentTimeMillis", "()J", false);
                mv.visitVarInsn(Opcodes.LSTORE, 1);  // 保存开始时间
                super.visitCode();
            }
            
            @Override
            public void visitInsn(int opcode) {
                // 方法返回前：打印耗时
                if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) 
                    || opcode == Opcodes.ATHROW) {
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, 
                        "java/lang/System", "currentTimeMillis", "()J", false);
                    mv.visitVarInsn(Opcodes.LLOAD, 1);  // 加载开始时间
                    mv.visitInsn(Opcodes.LSUB);         // 计算耗时
                    mv.visitVarInsn(Opcodes.LSTORE, 3); // 保存耗时
                    
                    // System.out.println("耗时: " + time);
                    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", 
                        "out", "Ljava/io/PrintStream;");
                    mv.visitVarInsn(Opcodes.LLOAD, 3);
                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, 
                        "java/io/PrintStream", "println", "(J)V", false);
                }
                super.visitInsn(opcode);
            }
        };
    }
}

// 2. 使用Javassist
import javassist.*;

public class JavassistDemo {
    public static void main(String[] args) throws Exception {
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("com.example.MyClass");
        CtMethod m = cc.getDeclaredMethod("myMethod");
        
        // 方法前插入代码
        m.insertBefore("long start = System.currentTimeMillis();");
        
        // 方法后插入代码
        m.insertAfter("System.out.println(\"耗时: \" + " +
            "(System.currentTimeMillis() - start));");
        
        // 加载修改后的类
        Class<?> clazz = cc.toClass();
        Object instance = clazz.newInstance();
    }
}

// 3. 使用ByteBuddy
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

public class ByteBuddyDemo {
    public static void main(String[] args) throws Exception {
        Class<?> dynamicType = new ByteBuddy()
            .subclass(Object.class)
            .method(ElementMatchers.named("toString"))
            .intercept(MethodDelegation.to(Interceptor.class))
            .make()
            .load(ByteBuddyDemo.class.getClassLoader())
            .getLoaded();
        
        System.out.println(dynamicType.newInstance().toString());
    }
    
    public static class Interceptor {
        public static String intercept() {
            return "Intercepted!";
        }
    }
}

// 字节码增强应用场景
/*
1. AOP（面向切面编程）
   - Spring AOP
   - AspectJ
   - 方法拦截、事务管理

2. 动态代理
   - JDK动态代理
   - CGLib代理
   - Dubbo RPC

3. 监控埋点
   - 性能监控
   - 调用链追踪
   - 方法耗时统计

4. 热部署
   - JRebel
   - Spring DevTools
   - 类的热替换

5. 测试工具
   - Mock框架（Mockito）
   - 覆盖率工具（JaCoCo）
   - 字节码注入

6. 安全检查
   - 权限校验
   - 参数验证
   - 加密解密
*/`
			}
		]
	}
];